#include <libudev.h>     //include
#include <blkid/blkid.h> //include
#include <sys/sysmacros.h>
#include <fstream>
#include <sstream>
#include <mntent.h>
#include <cstring>
#include <sys/statvfs.h>
#include <sys/stat.h>
#include <iostream>
#include <vector>
#include <mntent.h>
#include <regex>
#include <unistd.h>
#include <filesystem>
#include <algorithm>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <cstdint>
#include <unistd.h>
#include <grp.h>
#include <stdexcept>
#include <string>
#include <memory>
#include "./StorageManager.hpp"
#include "StorageManager.hpp"
typedef enum
{
    DISK_TYPE_UNKNOWN = 0,
    DISK_TYPE_SATA_SCSI_USB, // /sd
    DISK_TYPE_NVME,          // /nvme
    DISK_TYPE_VIRTIO,        // /vd
    DISK_TYPE_XEN,           // /xvd
    DISK_TYPE_MMC,           // /mmcblk
} DiskType;
namespace fs = std::filesystem;
// 静态数据段开始-------------------------------------------------------------------------------
// std::set<std::string> Storage_manager::disk_names;
// 外部接口开始--------------------------------------------------------------------------------
StorageManager::StorageManager()
{
    // if (isUserInDiskGroup()==false)
    // {
    //     throw std::runtime_error("Current user is not in the 'disk' group");
    // }
    this->m_disks_info = *new DataStructure();
    m_disks_info.p_disks_list = new SinglePhysicalDiskInfo[1024];
    this->m_disks_info.num_of_disks = 0;
    UpdateDisksInfo();
}
StorageManager::~StorageManager()
{
    std::cout << "Storage_manager class object ends";
}
int StorageManager::GetDiskNameList(std::vector<std::string> &disks_list)
{
    // 清空输出列表
    disks_list = *new std::vector<std::string>();

    // 遍历所有磁盘
    for (int i = 0; i < m_disks_info.num_of_disks; ++i)
    {
        // 添加磁盘设备路径到列表
        disks_list.push_back(m_disks_info.p_disks_list[i].disk_device_path);
    }

    return 0; // 成功返回0
}
int StorageManager::GetSingleDiskInfo(SinglePhysicalDiskInfo &disk_info, std::string disk_device_path)
{
    // 查找匹配的磁盘
    SinglePhysicalDiskInfo *found = nullptr;
    for (int i = 0; i < m_disks_info.num_of_disks; ++i)
    {
        if (m_disks_info.p_disks_list[i].disk_device_path == disk_device_path)
        {
            found = &m_disks_info.p_disks_list[i];
            break;
        }
    }

    // 检查是否找到
    if (!found)
        return 1; // 错误码1：无效设备路径

    // 复制基本数据
    disk_info.disk_device_path = found->disk_device_path;
    disk_info.disk_id = found->disk_id;
    disk_info.disk_total_space_mbyte = found->disk_total_space_mbyte;
    disk_info.disk_free_space_mbyte = found->disk_free_space_mbyte;
    disk_info.partition_numbers = found->partition_numbers;

    // 处理分区列表深拷贝
    if (found->partition_numbers > 0)
    {
        try
        {
            // 分配新内存
            disk_info.p_partitions_list = new SinglePhysicalPartitionInfo[found->partition_numbers];

            // 复制每个分区数据
            for (int i = 0; i < found->partition_numbers; ++i)
            {
                disk_info.p_partitions_list[i] = found->p_partitions_list[i];
            }
        }
        catch (...)
        {
            return 2; // 错误码2：内存分配失败
        }
    }
    else
    {
        disk_info.p_partitions_list = nullptr;
    }

    return 0; // 成功返回0
}

int StorageManager::GetDiskInfoList(DataStructure &disks_list)
{
    disks_list = *new DataStructure();
    disks_list.num_of_disks = m_disks_info.num_of_disks;
    disks_list.p_disks_list = new SinglePhysicalDiskInfo[m_disks_info.num_of_disks];
    for (int i = 0; i < m_disks_info.num_of_disks; i++)
    {
        disks_list.p_disks_list[i] = m_disks_info.p_disks_list[i];
        disks_list.p_disks_list[i].p_partitions_list = new SinglePhysicalPartitionInfo[m_disks_info.p_disks_list[i].partition_numbers];
        for (int j = 0; j < m_disks_info.p_disks_list[i].partition_numbers; j++)
        {
            disks_list.p_disks_list[i].p_partitions_list[j] = m_disks_info.p_disks_list[i].p_partitions_list[j];
        }
    }
    return 0;
}

void StorageManager::RunTest()
{
    PrintDiskInfo();
    return;
}
int StorageManager::PrintDiskInfo()
{
    std::cout << "Print function begins:" << std::endl;
    for (int i = 0; i < this->m_disks_info.num_of_disks; i++)
    {
        std::cout << "Disk MAX:MIN " << this->m_disks_info.p_disks_list[i].disk_id << std::endl;
        std::cout << "Disk total space " << this->m_disks_info.p_disks_list[i].disk_total_space_mbyte << "MByte" << std::endl;
        std::cout << this->m_disks_info.p_disks_list->disk_device_path << std::endl;
        for (int j = 0; j < this->m_disks_info.p_disks_list[i].partition_numbers; j++)
        {
            std::cout << this->m_disks_info.p_disks_list[i].p_partitions_list[j].partition_device_path << std::endl;
            std::cout << this->m_disks_info.p_disks_list[i].p_partitions_list[j].mount_point << std::endl;
            std::cout << "Total space " << this->m_disks_info.p_disks_list[i].p_partitions_list[j].total_space_mbyte << " MB" << std::endl;
            std::cout << "Free space " << this->m_disks_info.p_disks_list[i].p_partitions_list[j].free_space_mbyte << " MB" << std::endl;
        }
        std::cout << std::endl;
    }
    std::cout << "Print function ends:" << std::endl;
    return 0;
}
// 直接调用函数开始----------------------------------------------------------------------------
int StorageManager::UpdateDisksInfo()
{
    // DataStructure Info;
    this->InitDisksInfo();
    return 0;
}

// 间接调用函数开始----------------------------------------------------------------------------

int StorageManager::IsPhysicalDisk(std::string disk_device_path)
{
    disk_device_path = "";
    if (1)
        return 1;
    else
        return 0;
}

std::set<std::string> StorageManager::InitDisksInfo() // 应该叫init_disks_info();
{
    // 创建返回对象
    std::set<std::string> set_disk_names;
    // 创建udev上下文环境
    // udev_new() - 初始化并返回一个新的udev上下文
    // 这是所有udev操作的基础，必须先创建
    struct udev *udev = udev_new();
    if (!udev)
    {
        std::cerr << "Failed to create udev context" << std::endl;
        return set_disk_names;
    }

    // 创建枚举器用于扫描设备
    // udev_enumerate_new() - 创建一个新的设备枚举器
    struct udev_enumerate *enumerate = udev_enumerate_new(udev);

    // 添加匹配条件：只扫描block子系统(块设备)
    // udev_enumerate_add_match_subsystem() - 限制枚举特定子系统的设备
    udev_enumerate_add_match_subsystem(enumerate, "block");

    // 开始扫描设备
    // udev_enumerate_scan_devices() - 执行设备扫描
    udev_enumerate_scan_devices(enumerate);

    // 获取设备列表
    // udev_enumerate_get_list_entry() - 返回扫描到的设备链表
    struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
    struct udev_list_entry *entry;

    // 遍历设备列表
    // udev_list_entry_foreach - 宏定义，用于遍历udev_list_entry链表
    udev_list_entry_foreach(entry, devices)
    {
        // 获取设备在sysfs中的路径
        // udev_list_entry_get_name() - 获取当前条目对应的sysfs路径
        const char *path = udev_list_entry_get_name(entry);

        // 从sysfs路径创建设备对象
        // udev_device_new_from_syspath() - 根据sysfs路径创建udev设备对象
        struct udev_device *device = udev_device_new_from_syspath(udev, path);

        // 获取设备节点路径(如/dev/sda)
        // udev_device_get_devnode() - 返回设备节点路径
        const char *devnode = udev_device_get_devnode(device);

        // 获取设备类型
        // udev_device_get_devtype() - 返回设备类型字符串
        const char *devtype = udev_device_get_devtype(device);

        // 只显示磁盘设备而非分区
        // 检查设备类型是否为"disk"(排除分区等其他块设备)
        if (devnode && devtype && strcmp(devtype, "disk") == 0)
        {
            if (devnode && devtype && strcmp(devtype, "disk") == 0)
            {
                if (strstr(devnode, "/sd") ||   // SATA/SCSI/USB
                    strstr(devnode, "/nvme") || // NVMe
                    strstr(devnode, "/vd") ||   // Virt_iO
                    strstr(devnode, "/xvd") ||  // Xen
                    strstr(devnode, "/mmcblk")) // e_mMC/SD卡
                {
                    std::cout << "Physical Disk from get_disk_names（）: " << devnode << std::endl;
                    // 得到磁盘类型，传参给下一个函数
                    //  get_disk_type();
                    //  保存这个磁盘到内存
                    this->SaveDiskNameToStruct(devnode);
                }
            }
        }

        // 释放设备对象
        // udev_device_unref() - 减少设备对象的引用计数
        udev_device_unref(device);
    }

    // 清理资源
    // udev_enumerate_unref() - 释放枚举器
    udev_enumerate_unref(enumerate);
    // udev_unref() - 释放udev上下文
    udev_unref(udev);
    return set_disk_names;
}

std::vector<std::string> StorageManager::GetSataDevicePathsOfPartitions(const std::string &disk_device_path) // 从磁盘物理路径获取分区路径
{
    std::vector<std::string> partitions;
    blkid_probe pr = blkid_new_probe_from_filename(disk_device_path.c_str());

    if (!pr)
    {
        std::cerr << "Failed to open ,reboot process with sudo" << disk_device_path << std::endl;
        return partitions;
    }

    // 获取分区表
    blkid_partlist ls;
    ls = blkid_probe_get_partitions(pr);

    if (!ls)
    {
        std::cerr << "No partition table found on " << disk_device_path << std::endl;
        blkid_free_probe(pr);
        return partitions;
    }

    int nparts = blkid_partlist_numof_partitions(ls);
    for (int i = 0; i < nparts; ++i)
    {
        blkid_partition part = blkid_partlist_get_partition(ls, i);
        if (part)
        {
            std::string part_name = disk_device_path + std::to_string(blkid_partition_get_partno(part));
            partitions.push_back(part_name);
        }
    }

    blkid_free_probe(pr);
    return partitions;
}

int StorageManager::SaveDiskNameToStruct(std::string disk_device_path) // 在这里保存磁盘的分区信息,同时在这里保存磁盘信息，是initDisks的子函数
{
    std::string type = "unknown";
    std::regex pattern(R"((sd|nvme|vd|xvd|mmcblk))");
    std::smatch matches;
    if (std::regex_search(disk_device_path, matches, pattern))
    {
        type = matches[1].str(); // 提取匹配的磁盘前缀
    }

    //写信息：
    //linux C++开发，用smartmontools库读取磁盘类型。现在有磁盘设备地址std::string disk_device_path和
    //磁盘类型std::string type两个变量，现在写代码段，声明smart信息结构


    this->m_disks_info.p_disks_list[this->m_disks_info.num_of_disks].disk_device_path = disk_device_path;
    this->m_disks_info.p_disks_list[this->m_disks_info.num_of_disks].disk_type=type;
    this->m_disks_info.num_of_disks++; // 指向下一个，this->m_disks_info.num_of_disks的默认值为0

    InitPartitionsInfo(disk_device_path);
    CompleteDiskInfo(disk_device_path);//initDisks的子函数，由于磁盘有信息需要在获取分区后得到，所以调用本函数，三个函数都是initDisk的子函数
    return 0;
}
int StorageManager::FindTheheIndexOfOneDiskInTheList(std::string disk_device_path)
{
    for (int i = 0; i < this->m_disks_info.num_of_disks; i++)
    {
        if (this->m_disks_info.p_disks_list[i].disk_device_path == disk_device_path)
        {
            return i;
        }
    }
    return -1;
}
int StorageManager::InitPartitionsInfo(std::string disk_device_path)
{
    int index = FindTheheIndexOfOneDiskInTheList(disk_device_path);
    //获取
    std::vector<std::string> partitions = GetSataDevicePathsOfPartitions(disk_device_path);
    this->m_disks_info.p_disks_list[index].partition_numbers = partitions.size();
    // std::cout << this->disks_info.p_disks_list[index].partition_numbers << std::endl;
    this->m_disks_info.p_disks_list[index].p_partitions_list = new SinglePhysicalPartitionInfo[256]; // MAX_PAETITION=256;
    int numOfPartitions = int(partitions.size());
    for (int j = 0; j < numOfPartitions; j++)
    {
        this->m_disks_info.p_disks_list[index].p_partitions_list[j].partition_device_path = partitions[j];
        this->m_disks_info.p_disks_list[index].p_partitions_list[j].mount_point = GetMountPointFromPartitioName(this->m_disks_info.p_disks_list[index].p_partitions_list[j].partition_device_path);
        if (this->m_disks_info.p_disks_list[index].p_partitions_list[j].mount_point == "")
        {
            this->m_disks_info.p_disks_list[index].p_partitions_list[j].mount_point = "Partition not mounted";
            std::vector<int> space_info = GetNotMountedPartitionSpaceInfo(this->m_disks_info.p_disks_list[index].p_partitions_list[j].partition_device_path);
            this->m_disks_info.p_disks_list[index].p_partitions_list[j].total_space_mbyte = space_info[0];
            this->m_disks_info.p_disks_list[index].p_partitions_list[j].free_space_mbyte = space_info[1];
        }
        else
        {
            std::vector<int> space_info = GetPartitionSpaceInfo(this->m_disks_info.p_disks_list[index].p_partitions_list[j].mount_point);
            this->m_disks_info.p_disks_list[index].p_partitions_list[j].total_space_mbyte = space_info[0];
            this->m_disks_info.p_disks_list[index].p_partitions_list[j].free_space_mbyte = space_info[1];
        }
    }

    return 0;
}

std::string StorageManager::GetMountPointFromPartitioName(const std::string &disk_device_path)
{
    FILE *mtab = setmntent("/etc/mtab", "r");
    if (!mtab)
    {
        return "";
    }

    struct mntent *mnt;
    while ((mnt = getmntent(mtab)) != nullptr)
    {
        if (std::string(mnt->mnt_fsname) == disk_device_path)
        {
            endmntent(mtab);
            return mnt->mnt_dir;
        }
    }
    endmntent(mtab);
    return "";
}

std::vector<int> StorageManager::GetPartitionSpaceInfo(const std::string &partition_mount_point_path)
{
    std::vector<int> space_info(2, 0); // [0] = total, [1] = free

    struct statvfs vfs;
    if (statvfs(partition_mount_point_path.c_str(), &vfs) == 0)
    {
        // 使用 uint64_t 防止溢出
        uint64_t total_bytes = static_cast<uint64_t>(vfs.f_blocks) * vfs.f_bsize;
        uint64_t free_bytes = static_cast<uint64_t>(vfs.f_bavail) * vfs.f_bsize;

        // 转换为 MB（1MB = 1024*1024 Bytes）
        space_info[0] = static_cast<int>(total_bytes / (1024 * 1024));
        space_info[1] = static_cast<int>(free_bytes / (1024 * 1024));
    }
    else
    {
        std::cerr << "Error getting filesystem statistics for " << partition_mount_point_path << std::endl;
    }

    return space_info;
}

int StorageManager::CompleteDiskInfo(std::string disk_device_path)
{
    std::string disk_id;
    int disk_total_space_mbyte;
    try
    {
        // 获取磁盘总空间大小（使用statvfs）
        int fd = open("/dev/sda", O_RDONLY);
        uint64_t size;
        ioctl(fd, BLKGETSIZE64, &size); // 获取字节数
        disk_total_space_mbyte = size / (1024 * 1024);
        close(fd);
        // 获取磁盘标识符（从/sys/block/...）
        std::string base_name = disk_device_path.substr(disk_device_path.find_last_of("/") + 1);
        std::string sysfs_path = "/sys/block/" + base_name + "/device/model";

        std::ifstream model_file(sysfs_path);
        if (model_file.is_open())
        {
            std::getline(model_file, disk_id);
            model_file.close();
        }
        else
        {
            // 如果无法读取model，使用设备名称作为ID
            disk_id = base_name;
        }

        // 获取MIN:MAX信息（这里假设你想获取的是设备号）
        std::string dev_path = "/dev/" + base_name;
        struct stat st;
        if (stat(dev_path.c_str(), &st) == 0)
        {
            // 主设备号和次设备号
            unsigned int major = major(st.st_rdev);
            unsigned int minor = minor(st.st_rdev);
            char buffer[100];
            sprintf(buffer, "%d:%d", major, minor);
            disk_id = buffer;
            // 你可以在这里处理这些信息，或者将它们保存到其他变量
            std::cout << "Device number: " << major << ":" << minor << std::endl;
        }

        //-----------------
        // 现在disk_id和disk_total_space_mbyte已经包含所需信息
        // 你可以在这里将它们保存到你的对象中
        int index = FindTheheIndexOfOneDiskInTheList(disk_device_path);
        this->m_disks_info.p_disks_list[index].disk_id = disk_id;
        this->m_disks_info.p_disks_list[index].disk_total_space_mbyte = disk_total_space_mbyte;
        this->m_disks_info.p_disks_list[index].disk_free_space_mbyte = -1;
        std::cout << "disk_total_space_mbyte " << disk_total_space_mbyte << "MB" << std::endl;

        return 0;
    }
    catch (const std::exception &e)
    {
        std::cerr << "Exception in complete_disk_info: " << e.what() << std::endl;
        return -1;
    }
}
std::vector<int> StorageManager::GetNotMountedPartitionSpaceInfo(const std::string &partition_device_path)
{
    std::string device = partition_device_path;
    ;
    int fd = open(device.c_str(), O_RDONLY);
    if (fd == -1)
    {
        perror("open");
        return {-1, -1};
    }

    uint64_t size = 0;
    if (ioctl(fd, BLKGETSIZE64, &size) == -1)
    {
        perror("ioctl");
        close(fd);
        return {-1, -1};
    }

    close(fd);

    std::cout << "Partition size: " << size << " bytes ("
              << size / (1024 * 1024) << " MB)" << std::endl;

    return {int((size / (1024 * 1024))), -1};
}

// 打印单个分区信息
int printSinglePartitionInfo(const SinglePhysicalPartitionInfo &partition)
{
    std::cout << "  Partition Device Path: " << partition.partition_device_path << std::endl;
    std::cout << "  Total Space: " << partition.total_space_mbyte << " MB" << std::endl;
    std::cout << "  Free Space: " << partition.free_space_mbyte << " MB" << std::endl;
    std::cout << "  Mount Point: " << partition.mount_point << std::endl;
    std::cout << "  --------------------" << std::endl;
    return 0;
}

// 打印单个磁盘信息
int printSingleDiskInfo(const SinglePhysicalDiskInfo &disk)
{
    std::cout << "Disk Device Path: " << disk.disk_device_path << std::endl;
    std::cout << "Disk ID: " << disk.disk_id << std::endl;
    std::cout << "Total Disk Space: " << disk.disk_total_space_mbyte << " MB" << std::endl;
    std::cout << "Free Disk Space: " << disk.disk_free_space_mbyte << " MB" << std::endl;
    std::cout << "Number of Partitions: " << disk.partition_numbers << std::endl;

    if (disk.partition_numbers > 0 && disk.p_partitions_list != nullptr)
    {
        std::cout << "Partition Details:" << std::endl;
        for (int i = 0; i < disk.partition_numbers; ++i)
        {
            printSinglePartitionInfo(disk.p_partitions_list[i]);
        }
    }
    std::cout << "====================" << std::endl;
    return 0;
}

// 打印整个数据结构
int printDataStructure(const DataStructure &data)
{
    std::cout << "Number of Disks: " << data.num_of_disks << std::endl;

    if (data.num_of_disks > 0 && data.p_disks_list != nullptr)
    {
        for (int i = 0; i < data.num_of_disks; ++i)
        {
            printSingleDiskInfo(data.p_disks_list[i]);
        }
    }
    return 0;
}
int StorageManager::printSinglePartitionInfo(const SinglePhysicalPartitionInfo &partition)
{
    std::cout << "Partition Device Path: " << partition.partition_device_path << std::endl;
    std::cout << "Total Space (MB): " << partition.total_space_mbyte << std::endl;
    std::cout << "Free Space (MB): " << partition.free_space_mbyte << std::endl;
    std::cout << "Mount Point: " << partition.mount_point << std::endl;
    std::cout << "--------------------------------" << std::endl;
    return 0;
}

int StorageManager::printSingleDiskInfo(const SinglePhysicalDiskInfo &disk)
{
    std::cout << "==== Disk Information ====" << std::endl;
    std::cout << "Disk Device Path: " << disk.disk_device_path << std::endl;
    std::cout << "Disk Device Type: " << disk.disk_type << std::endl;
    std::cout << "Disk ID: " << disk.disk_id << std::endl;
    std::cout << "Total Disk Space (MB): " << disk.disk_total_space_mbyte << std::endl;
    std::cout << "Free Disk Space (MB): " << disk.disk_free_space_mbyte << std::endl;
    std::cout << "Number of Partitions: " << disk.partition_numbers << std::endl;
    std::cout << "--------------------------------" << std::endl;

    // 打印该磁盘的所有分区信息
    for (int i = 0; i < disk.partition_numbers; ++i)
    {
        std::cout << "Partition #" << i + 1 << ":" << std::endl;
        printSinglePartitionInfo(disk.p_partitions_list[i]);
    }
    return 0;
}

int StorageManager::printDataStructure(const DataStructure &data)
{
    std::cout << "**** Storage System Overview ****" << std::endl;
    std::cout << "Total Number of Disks: " << data.num_of_disks << std::endl;
    std::cout << "=================================" << std::endl;

    // 打印所有磁盘及其分区信息
    for (int i = 0; i < data.num_of_disks; ++i)
    {
        std::cout << "Disk #" << i + 1 << ":" << std::endl;
        printSingleDiskInfo(data.p_disks_list[i]);
    }
    return 0;
}
bool StorageManager::isUserInDiskGroup()
{
    struct group *grp = getgrnam("disk");
    if (!grp)
    {
        std::cerr << "Error: 'disk' group not found" << std::endl;
        throw std::runtime_error("'disk' group not found");
    }

    gid_t disk_gid = grp->gr_gid;
    std::cout << "Disk group ID: " << disk_gid << std::endl;

    // 获取当前进程的组列表
    int ngroups = getgroups(0, nullptr);
    std::cout << "Number of groups: " << ngroups << std::endl;
    if (ngroups <= 0)
    {
        std::cerr << "Error: getgroups failed to get group count" << std::endl;
        return false;
    }

    gid_t *groups = new gid_t[ngroups];
    ngroups = getgroups(ngroups, groups);
    if (ngroups == -1)
    {
        std::cerr << "Error: getgroups failed with error: " << errno << std::endl;
        delete[] groups;
        return false;
    }

    std::cout << "User's group IDs: ";
    for (int i = 0; i < ngroups; ++i)
    {
        std::cout << groups[i] << " ";
        if (groups[i] == disk_gid)
        {
            std::cout << "\nFound disk group in user's groups" << std::endl;
            delete[] groups;
            return true;
        }
    }
    std::cout << std::endl;

    delete[] groups;
    std::cerr << "Disk group not found in user's groups" << std::endl;
    return false;
}

std::string StorageManager::FindPartitionUUID(std::string partition_device_path)
{
    blkid_probe pr = blkid_new_probe_from_filename(partition_device_path.c_str());
    if (!pr) {
        return "";// NULL
    }

    const char* uuid = nullptr;
    blkid_do_probe(pr);
    blkid_probe_lookup_value(pr, "UUID", &uuid, nullptr);

    std::string result(uuid ? uuid : "");
    blkid_free_probe(pr);
    return result;
}

// 本程序独立函数定义-----------------------------------------------------------------------------------------
const char *disk_type_to_string(DiskType type)
{
    switch (type)
    {
    case DISK_TYPE_SATA_SCSI_USB:
        return "SATA/SCSI/USB";
    case DISK_TYPE_NVME:
        return "NVMe";
    case DISK_TYPE_VIRTIO:
        return "VirtIO";
    case DISK_TYPE_XEN:
        return "Xen";
    case DISK_TYPE_MMC:
        return "eMMC/SD";
    default:
        return "Unknown";
    }
}

DiskType get_disk_type(const char *devnode)
{
    if (strstr(devnode, "/sd"))
    {
        return DISK_TYPE_SATA_SCSI_USB;
    }
    else if (strstr(devnode, "/nvme"))
    {
        return DISK_TYPE_NVME;
    }
    else if (strstr(devnode, "/vd"))
    {
        return DISK_TYPE_VIRTIO;
    }
    else if (strstr(devnode, "/xvd"))
    {
        return DISK_TYPE_XEN;
    }
    else if (strstr(devnode, "/mmcblk"))
    {
        return DISK_TYPE_MMC;
    }
    return DISK_TYPE_UNKNOWN;
}
